#region using
using System;
#endregion

namespace DbmlManager.Lib.Utility
{
  #region Class Docs
	/// <summary>
	/// Summary description for ChangeableObjectBase.
	/// </summary>
  #endregion

	public class ChangeableObjectBase : IChangeableObject
	{
    // Constructors

    #region ChangleableObjectBase()
		public ChangeableObjectBase()
		{
    }
    #endregion

    // Private Properties

    #region SyncEvents
    private object SyncEvents
    {
      get
      {
        return _syncEvents;
      }
    }
    private object _syncEvents = new object();
    #endregion

    // Public Properties

    #region HasChanges
    public bool HasChanges
    {
      get
      {
        return _hasChanges;
      }
    }
    protected bool _hasChanges = false;
    #endregion

    // Public Methods

    #region ClearChanges()
    public void ClearChanges()
    {
      _hasChanges = false;
    }
    #endregion

    #region Copy(IChangeableObject obj)
    public void Copy(IChangeableObject obj)
    {
      _hasChanges = obj.HasChanges;
    }
    #endregion

    // Public Events

    #region ObjectChanged
    public event System.EventHandler ObjectChanged
    {
      add
      {
        lock (SyncEvents)
        {
          _objectChanged += value;
        }
      }
      remove
      {
        lock (SyncEvents)
        {
          _objectChanged -= value;
        }
      }
    }
    private event System.EventHandler _objectChanged;
    #endregion

    // Protected Methods

    #region SetStringVal(ref string s, string newVal)
    protected void SetStringVal(ref string s, string newVal)
    {
      string oldVal = s;
      s = newVal;

      if (oldVal != newVal && !HasChanges)
      {
        // Only fire the ObjectChanged event the first time
        // a field within the object changes.
        _hasChanges = true;
        FireObjectChangedEvent();
      }
    }
    #endregion

    #region SetDateTimeVal(ref DateTime dt, DateTime newVal)
    protected void SetDateTimeVal(ref DateTime dt, DateTime newVal)
    {
      DateTime oldVal = dt;
      dt = newVal;

      if (oldVal != newVal && !HasChanges)
      {
        // Only fire the ObjectChanged event the first time
        // a field within the object changes.
        _hasChanges = true;
        FireObjectChangedEvent();
      }
    }
    #endregion

    #region SetBoolVal(ref bool b, bool newVal)
    protected void SetBoolVal(ref bool b, bool newVal)
    {
      bool oldVal = b;
      b = newVal;

      if (oldVal != newVal && !HasChanges)
      {
        // Only fire the ObjectChanged event the first time
        // a field within the object changes.
        _hasChanges = true;
        FireObjectChangedEvent();
      }
    }
    #endregion

    #region SetIntVal(ref int i, int newVal)
    protected void SetIntVal(ref int i, int newVal)
    {
      int oldVal = i;
      i = newVal;

      if (oldVal != newVal && !HasChanges)
      {
        // Only fire the ObjectChanged event the first time
        // a field within the object changes.
        _hasChanges = true;
        FireObjectChangedEvent();
      }
    }
    #endregion

    #region FireObjectChangedEvent()
    protected void FireObjectChangedEvent()
    {
      lock (SyncEvents)
      {
        if (_objectChanged != null)
          _objectChanged(this, null);
      }
    }
    #endregion
  }
}
